home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connectio…eloper Series 2005 March / Dev.CD Mar 05.iso / What's New / Sample Code / HIObjectThreadController / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  2004-06-22  |  15.2 KB  |  397 lines

  1. /*
  2. *    File:        main.c of HIObjectThreadController
  3.     Contains:    Shows how to control thread from UI and how threads can "control" UI.
  4. *
  5. *  Note:        The project is set up so that the DEBUG macro is set to one when the "Development"
  6. *                build style is chosen and not at all when the "Deployment" build style is chosen.
  7. *                Thus, all the require asserts "fire" only in "Development".
  8. *    
  9. *    Version:    1.0
  10. *    Created:    May 13th, 2004
  11. *
  12. *    Disclaimer:    IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc.
  13. *                ("Apple") in consideration of your agreement to the following terms, and your
  14. *                use, installation, modification or redistribution of this Apple software
  15. *                constitutes acceptance of these terms.  If you do not agree with these terms,
  16. *                please do not use, install, modify or redistribute this Apple software.
  17. *
  18. *                In consideration of your agreement to abide by the following terms, and subject
  19. *                to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
  20. *                copyrights in this original Apple software (the "Apple Software"), to use,
  21. *                reproduce, modify and redistribute the Apple Software, with or without
  22. *                modifications, in source and/or binary forms; provided that if you redistribute
  23. *                the Apple Software in its entirety and without modifications, you must retain
  24. *                this notice and the following text and disclaimers in all such redistributions of
  25. *                the Apple Software.  Neither the name, trademarks, service marks or logos of
  26. *                Apple Computer, Inc. may be used to endorse or promote products derived from the
  27. *                Apple Software without specific prior written permission from Apple.  Except as
  28. *                expressly stated in this notice, no other rights or licenses, express or implied,
  29. *                are granted by Apple herein, including but not limited to any patent rights that
  30. *                may be infringed by your derivative works or by other works in which the Apple
  31. *                Software may be incorporated.
  32. *
  33. *                The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
  34. *                WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
  35. *                WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  36. *                PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
  37. *                COMBINATION WITH YOUR PRODUCTS.
  38. *
  39. *                IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
  40. *                CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  41. *                GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  42. *                ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
  43. *                OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
  44. *                (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
  45. *                ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  46. *
  47. *    Copyright:  Copyright © 2004 Apple Computer, Inc, All Rights Reserved
  48. */
  49. //****************************************************
  50. #pragma mark * compilation directives *
  51.  
  52. //****************************************************
  53. #pragma mark -
  54. #pragma mark * includes & imports *
  55.  
  56. #include <Carbon/Carbon.h>
  57. #include "SomeTasks.h"
  58. #include "HIObjectThreadController.h"
  59.  
  60. //****************************************************
  61. #pragma mark -
  62. #pragma mark * typedef's, struct's, enums, defines, etc. *
  63.  
  64. //****************************************************
  65. #pragma mark -
  66. #pragma mark * local (static) function prototypes *
  67.  
  68. static pascal OSErr Handle_OpenApplication(const AppleEvent *inAppleEvent, AppleEvent *outAppleEvent, long inHandlerRefcon);
  69. static pascal OSErr Handle_ReopenApplication(const AppleEvent *inAppleEvent, AppleEvent *outAppleEvent, long inHandlerRefcon);
  70. static pascal OSErr Handle_OpenDocuments(const AppleEvent *inAppleEvent, AppleEvent *outAppleEvent, long inHandlerRefcon);
  71. static pascal OSErr Handle_PrintDocuments(const AppleEvent *inAppleEvent, AppleEvent *outAppleEvent, long inHandlerRefcon);
  72. static void Install_AppleEventHandlers(void);
  73.  
  74. static pascal OSStatus Handle_CommandUpdateStatus(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData);
  75. static pascal OSStatus Handle_CommandProcess(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData);
  76.  
  77. static void Do_Preferences(void);
  78. static OSStatus Do_CleanUp(void);
  79.  
  80. //****************************************************
  81. #pragma mark -
  82. #pragma mark * exported globals *
  83.  
  84. //****************************************************
  85. #pragma mark -
  86. #pragma mark * local (static) globals *
  87.  
  88. IBNibRef gIBNibRef;
  89.  
  90. //****************************************************
  91. #pragma mark -
  92. #pragma mark * exported function implementations *
  93.  
  94. /*****************************************************
  95. *
  96. * main (argc, argv) 
  97. *
  98. * Purpose:  main program entry point
  99. *
  100. * Notes:       You might want to change this to something more verbose
  101. *
  102. * Inputs:   argc     - the number of elements in the argv array
  103. *            argv     - an array of pointers to the parameters to this application
  104. *
  105. * Returns:  int      - error code (0 == no error) 
  106. */
  107. int main(int argc, char* argv[])
  108.     {
  109.     OSStatus status;
  110.     
  111.     // Can we run this particular demo application?
  112.     long response;
  113.     status = Gestalt(gestaltSystemVersion, &response);
  114.     Boolean ok = ((status == noErr) && (response >= 0x00001030));
  115.     if (!ok)
  116.         {
  117.         DialogRef theAlert;
  118.         CreateStandardAlert(kAlertStopAlert, CFSTR("Mac OS X 10.3 (minimum) is required for this application"), NULL, NULL, &theAlert);
  119.         RunStandardAlert(theAlert, NULL, NULL);
  120.         ExitToShell();
  121.         }
  122.     
  123.     // Create a Nib reference passing the name of the nib file (without the .nib extension)
  124.     // CreateNibReference only searches into the application bundle.
  125.     status = CreateNibReference(CFSTR("main"), &gIBNibRef);
  126.     require_noerr(status, CantGetNibRef);
  127.     
  128.     // Once the nib reference is created, set the menu bar. "MainMenu" is the name of the menu bar
  129.     // object. This name is set in InterfaceBuilder when the nib is created.
  130.     status = SetMenuBarFromNib(gIBNibRef, CFSTR("MenuBar"));
  131.     require_noerr(status, CantSetMenuBar);
  132.     
  133.     // Enabling Preferences menu item
  134.     EnableMenuCommand(NULL, kHICommandPreferences);
  135.     
  136.     // Let's react to User's commands.
  137.     Install_AppleEventHandlers();
  138.     
  139.     EventTypeSpec eventTypeCP = {kEventClassCommand, kEventCommandProcess};
  140.     InstallEventHandler(GetApplicationEventTarget(), Handle_CommandProcess, 1, &eventTypeCP, NULL, NULL);
  141.     
  142.     EventTypeSpec eventTypeCUS = {kEventClassCommand, kEventCommandUpdateStatus};
  143.     InstallEventHandler(GetApplicationEventTarget(), Handle_CommandUpdateStatus, 1, &eventTypeCUS, NULL, NULL);
  144.     
  145.     // Call the event loop
  146.     RunApplicationEventLoop();
  147.     
  148. CantSetMenuBar:
  149. CantGetNibRef:
  150.     return status;
  151.     }   // main
  152.  
  153. /*****************************************************/
  154. #pragma mark -
  155. #pragma mark * local (static) function implementations *
  156. #pragma mark * AppleEvent Handlers *
  157.  
  158. /*****************************************************
  159. *
  160. * Handle_OpenApplication(inAppleEvent, reply, inHandlerRefcon) 
  161. *
  162. * Purpose:  AppleEvent handler for the kAEOpenApplication event
  163. *
  164. * Inputs:   inAppleEvent    - the Apple event
  165. *           reply            - our reply to the Apple event
  166. *           inHandlerRefcon    - refcon passed to AEInstallEventHandler when this hander was installed
  167. *
  168. * Returns:  OSErr            - error code (0 == no error) 
  169. */
  170. static pascal OSErr Handle_OpenApplication(const AppleEvent *inAppleEvent, AppleEvent *outAppleEvent, long inHandlerRefcon)
  171.     {
  172.     // Create the first thread.
  173.     return HIObjectThreadControllerCreate(CFSTR("Leibniz"), SetUpLeibniz, CalculatingPiUsingLeibnizSimpleTask, TermLeibniz, kSTEndIteration / kSTUIIteration, NULL, NULL);
  174.     }   // Handle_OpenApplication
  175.  
  176. /*****************************************************
  177. *
  178. * Handle_ReopenApplication(inAppleEvent, reply, inHandlerRefcon) 
  179. *
  180. * Purpose:  AppleEvent handler for the kAEReopenApplication event
  181. *
  182. * Inputs:   inAppleEvent    - the Apple event
  183. *           reply            - our reply to the Apple event
  184. *           inHandlerRefcon    - refcon passed to AEInstallEventHandler when this hander was installed
  185. *
  186. * Returns:  OSErr            - error code (0 == no error) 
  187. */
  188. static pascal OSErr Handle_ReopenApplication(const AppleEvent *inAppleEvent, AppleEvent *outAppleEvent, long inHandlerRefcon)
  189.     {
  190.     // We were already running but with no windows so we create an empty one.
  191.     WindowRef theWindow = GetFrontWindowOfClass(kDocumentWindowClass, true);
  192.     if (theWindow == NULL)
  193.         return HIObjectThreadControllerCreate(CFSTR("Leibniz"), SetUpLeibniz, CalculatingPiUsingLeibnizSimpleTask, TermLeibniz, kSTEndIteration / kSTUIIteration, NULL, NULL);
  194.     else
  195.         return noErr;
  196.     }   // Handle_ReopenApplication
  197.  
  198. /*****************************************************
  199. *
  200. * Handle_OpenDocuments(inAppleEvent, reply, inHandlerRefcon) 
  201. *
  202. * Purpose:  AppleEvent handler for the kAEOpenDocuments event
  203. *
  204. * Inputs:   inAppleEvent    - the Apple event
  205. *           reply            - our reply to the Apple event
  206. *           inHandlerRefcon    - refcon passed to AEInstallEventHandler when this hander was installed
  207. *
  208. * Returns:  OSErr            - error code (0 == no error) 
  209. */
  210. static pascal OSErr Handle_OpenDocuments(const AppleEvent *inAppleEvent, AppleEvent *outAppleEvent, long inHandlerRefcon)
  211.     {
  212.     return errAEEventNotHandled;
  213.     }   // Handle_OpenDocuments
  214.  
  215. /*****************************************************
  216. *
  217. * Handle_PrintDocuments(inAppleEvent, reply, inHandlerRefcon) 
  218. *
  219. * Purpose:  AppleEvent handler for the kAEPrintDocuments event
  220. *
  221. * Inputs:   inAppleEvent    - the Apple event
  222. *           reply           - our reply to the Apple event
  223. *           inHandlerRefcon - refcon passed to AEInstallEventHandler when this hander was installed
  224. *
  225. * Returns:  OSErr            - error code (0 == no error) 
  226. */
  227. static pascal OSErr Handle_PrintDocuments(const AppleEvent *inAppleEvent, AppleEvent *outAppleEvent, long inHandlerRefcon)
  228.     {
  229.     return errAEEventNotHandled;
  230.     }   // Handle_PrintDocuments
  231.  
  232. /*****************************************************
  233. *
  234. * Install_AppleEventHandlers(void) 
  235. *
  236. * Purpose:  installs the AppleEvent handlers
  237. *
  238. * Inputs:   none
  239. *
  240. * Returns:  none
  241. */
  242. static void Install_AppleEventHandlers(void)
  243.     {
  244.     OSErr    status;
  245.     status = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, Handle_OpenApplication, 0, false);
  246.     require_noerr(status, CantInstallAppleEventHandlerOpenAppl);
  247.     
  248.     status = AEInstallEventHandler(kCoreEventClass, kAEReopenApplication, Handle_ReopenApplication, 0, false);
  249.     require_noerr(status, CantInstallAppleEventHandlerReOpenAppl);
  250.     
  251.     status = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, Handle_OpenDocuments, 0, false);
  252.     require_noerr(status, CantInstallAppleEventHandlerOpenDocs);
  253.     
  254.     status = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, Handle_PrintDocuments, 0, false);
  255.     require_noerr(status, CantInstallAppleEventHandlerPrintDocs);
  256.     
  257.     // Note: Since RunApplicationEventLoop installs a Quit AE Handler, there is no need to do it here.
  258.     
  259. CantInstallAppleEventHandlerOpenAppl:
  260. CantInstallAppleEventHandlerReOpenAppl:
  261. CantInstallAppleEventHandlerOpenDocs:
  262. CantInstallAppleEventHandlerPrintDocs:
  263.     return;
  264.     }   // Install_AppleEventHandlers
  265.  
  266. #pragma mark -
  267. #pragma mark * CarbonEvent Handlers *
  268.  
  269. /*****************************************************
  270. *
  271. * Handle_CommandUpdateStatus(inHandlerCallRef, inEvent, inUserData) 
  272. *
  273. * Purpose:  called to update status of the commands, enabling or disabling the menu items
  274. *
  275. * Inputs:   inHandlerCallRef    - reference to the current handler call chain
  276. *                inEvent             - the event
  277. *           inUserData          - app-specified data you passed in the call to InstallEventHandler
  278. *
  279. * Returns:  OSStatus            - noErr indicates the event was handled
  280. *                                 eventNotHandledErr indicates the event was not handled and the Toolbox should take over
  281. */
  282. static pascal OSStatus Handle_CommandUpdateStatus(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
  283.     {
  284.     OSStatus status = eventNotHandledErr;
  285.     
  286.     HICommand aCommand;
  287.     GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &aCommand);
  288.     
  289.     WindowRef aWindowRef = GetFrontWindowOfClass(kDocumentWindowClass, true);
  290.         
  291.     if (aWindowRef == NULL)
  292.         {
  293.         switch (aCommand.commandID)
  294.             {
  295.             case kHICommandClose:
  296.                 DisableMenuItem(aCommand.menu.menuRef, aCommand.menu.menuItemIndex);
  297.                 break;
  298.             }
  299.         }
  300.     else
  301.         {
  302.         switch (aCommand.commandID)
  303.             {
  304.             case kHICommandClose:
  305.                 EnableMenuItem(aCommand.menu.menuRef, aCommand.menu.menuItemIndex);
  306.                 break;
  307.             }
  308.         }
  309.  
  310.     return status;
  311.     }   // Handle_CommandUpdateStatus
  312.  
  313. /*****************************************************
  314. *
  315. * Handle_CommandProcess(inHandlerCallRef, inEvent, inUserData) 
  316. *
  317. * Purpose:  called to process commands from Carbon events
  318. *
  319. * Inputs:   inHandlerCallRef    - reference to the current handler call chain
  320. *            inEvent             - the event
  321. *           inUserData          - app-specified data you passed in the call to InstallEventHandler
  322. *
  323. * Returns:  OSStatus            - noErr indicates the event was handled
  324. *                                 eventNotHandledErr indicates the event was not handled and the Toolbox should take over
  325. */
  326. static pascal OSStatus Handle_CommandProcess(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
  327.     {
  328.     HICommand aCommand;
  329.     OSStatus status = eventNotHandledErr;
  330.     
  331.     GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &aCommand);
  332.     
  333.     switch (aCommand.commandID)
  334.         {
  335.         case kHICommandPreferences:
  336.             Do_Preferences();
  337.             break;
  338.         case 'LEIT':
  339.             HIObjectThreadControllerCreate(CFSTR("Leibniz"), SetUpLeibniz, CalculatingPiUsingLeibnizSimpleTask, TermLeibniz, kSTEndIteration / kSTUIIteration, NULL, NULL);
  340.             break;
  341.         case 'WALT':
  342.             HIObjectThreadControllerCreate(CFSTR("Wallis"), SetUpWallis, CalculatingPiUsingWallisSimpleTask, TermWallis, kSTEndIteration / kSTUIIteration, NULL, NULL);
  343.             break;
  344.         case kHICommandQuit:
  345.             status = Do_CleanUp();
  346.             break;
  347.         }
  348.     return status;
  349.     }   // Handle_CommandProcess
  350.  
  351. #pragma mark -
  352. #pragma mark * Windows *
  353.  
  354. /*****************************************************
  355. *
  356. * Do_Preferences(void) 
  357. *
  358. * Purpose:  routine to display dialog to set our applications preferences
  359. *
  360. * Inputs:   none
  361. *
  362. * Returns:  none
  363. */
  364. static void Do_Preferences(void)
  365.     {
  366.     DialogRef theAlert;
  367.     CreateStandardAlert(kAlertStopAlert, CFSTR("No Preferences yet!"), NULL, NULL, &theAlert);
  368.     RunStandardAlert(theAlert, NULL, NULL);
  369.     }   // Do_Preferences
  370.  
  371. /*****************************************************
  372. *
  373. * Do_CleanUp(void) 
  374. *
  375. * Purpose:  called when we get the quit event, closes all the windows.
  376. *
  377. * Inputs:   none
  378. *
  379. * Returns:  OSStatus   - eventNotHandledErr indicates that the quit process can continue
  380. */
  381. static OSStatus Do_CleanUp(void)
  382.     {
  383.     WindowRef windowToDispose, aWindowRef = GetFrontWindowOfClass(kDocumentWindowClass, true);
  384.  
  385.     while (aWindowRef != NULL)
  386.     {
  387.         windowToDispose = aWindowRef;
  388.         aWindowRef = GetNextWindowOfClass(aWindowRef, kDocumentWindowClass, true);
  389.         
  390.         DisposeWindow(windowToDispose);
  391.     }
  392.     
  393.     return eventNotHandledErr;
  394.     }   // Do_CleanUp
  395.